
package member

import (
    "time"
    "errors"
    "strings"
    "dhfshop/models"
	"github.com/astaxie/beego/orm"
)

/***************************
余额使用的一些原则：
1. 账号里面：充值金额和赠送金额需要分开保存。
2. 消费时，优先消耗充值金额。
3. 如果顾客退掉充值金额时，充值金额可以退，赠送金额清0。
4. 交易中，需要对 两种金额分别记录。
5. 交易退款时，交易消耗的充值金额退回账号的充值金额，赠送金额退回 账号的 赠送金额账号。

***************************/
// 账户值对象
type Account struct {
	MemberId        int64    `orm:"column(member_id);pk" json:"member_id" form:"member_id"`                                /* 会员编号*/
	//PartnerId     int64      `orm:"column(partner_id);index" json:"partner_id" form:"partner_id"`
	AppId           string   `orm:"column(app_id);size(32);index" json:"app_id"`                                      /* 所属appid */
	Integral        int      `orm:"column(integral)" json:"integral" form:"integral"`                                       /* 积分 */
	FreezeIntegral  int      `orm:"column(freeze_integral)" json:"freeze_integral" form:"freeze_integral"`                  /* 冻结的积分*/
	Balance         float32  `orm:"column(balance);digits(12);decimals(2)" json:"balance" form:"balance"`                     /* 账户余额 */
	FreezeBalance float32 `orm:"column(freeze_balance);digits(12);decimals(2)" json:"freeze_balance" form:"freeze_balance"`/* 冻结的可用余额 */
	ExpiredBalance float32 `orm:"column(expired_balance);digits(12);decimals(2)" json:"expired_balance" form:"expired_balance"`/* 失效的账户余额 */
	Present         float32  `orm:"column(present);digits(12);decimals(2)" json:"present" form:"present"`              /* 赠送的可用金额 */
	FreezePresent float32 `orm:"column(freeze_present);digits(12);decimals(2)" json:"freeze_present" form:"freeze_present"` /* 冻结赠送金额 */
	ExpiredPresent float32 `orm:"column(expired_present);digits(12);decimals(2)" json:"expired_present" form:"expired_present"`/* 失效的赠送金额 */
	Bonus           float32  `orm:"column(bonus);digits(12);decimals(2)" json:"bonus" form:"bonus"`                    /* 红包余额 */
	TotalBonus      float32  `orm:"column(total_bonus);digits(12);decimals(2)" json:"total_bonus" form:"total_bonus"`  /* 总赠送红包额 */
	TotalPresent    float32  `orm:"column(total_present);digits(12);decimals(2)" json:"total_present" form:"total_present"`  /* 总赠送金额 */
	TotalConsume    float32  `orm:"column(total_consume);digits(12);decimals(2)" json:"total_expense" form:"total_expense"`  /* 总消费金额 */
	TotalCharge     float32  `orm:"column(total_charge);digits(12);decimals(2)" json:"total_charge" form:"total_charge"`    /* 总充值金额 */
	TotalPay        float32  `orm:"column(total_pay);digits(12);decimals(2)" json:"total_pay" form:"total_pay"`      /* 总支付额 */
	PriorityPay     int      `orm:"column(priority_pay)" json:"priority_pay" form:"priority_pay"`                /* 优先(默认)支付选项*/
	CreatedAt      time.Time `orm:"auto_now_add;column(created_at);type(datetime)" json:"-" form:"-"`           /* 创建时间 */
	UpdatedAt      time.Time `orm:"auto_now;column(updated_at);type(datetime)" json:"-" form:"-"`               /* 修改时间 */
}

// 钱包账户日志表,比如:京东的钱包账户相当于理财账户
type WalletLog struct {
	Id           int64   `orm:"column(id);pk;auto" json:"id" form:"id"` 
	//PartnerId    int64     `orm:"column(partner_id);index" json:"partner_id" form:"partner_id"`
	MemberId     int64     `orm:"column(member_id)" json:"member_id" form:"member_id"`      // 会员编号
	AppId        string   `orm:"column(app_id);size(32);index" json:"app_id"`                     //所属appid
	OuterNo      string  `orm:"column(outer_no);size(256);null" json:"outer_no" form:"outer_no"`  // 外部单号 
	BusinessKind int     `orm:"column(kind)" json:"kind" form:"kind"`                     /*业务类型*/
	Title        string  `orm:"column(title);size(256);null" json:"title" form:"title"`  // 标题
	Amount       float32 `orm:"column(amount);digits(12);decimals(2)" json:"amount" form:"amount"` /* 金额*/
	CsnFee       float32 `orm:"column(csn_fee);digits(12);decimals(2)" json:"csn_fee" form:"csn_fee"` /* 手续费*/
	RelateUser   int64   `orm:"column(rel_user)" json:"rel_user" form:"rel_user"` /*关联操作人,仅在客服操作时,记录操作人*/
	State        int     `orm:"column(state)" json:"state" form:"state"`                     /*状态*/
	Remark       string  `orm:"column(remark);size(256);null" json:"remark" form:"remark"`    //备注        
    CreatedAt  time.Time `orm:"auto_now_add;column(created_at);type(datetime)" json:"-" form:"-"`  //创建时间
	UpdatedAt  time.Time `orm:"auto_now;column(updated_at);type(datetime)" json:"-" form:"-"`      // 修改时间
}

type BankInfo struct {
	MemberId     int64   `orm:"column(member_id);pk" json:"member_id" form:"member_id"` 
	//PartnerId    int64     `orm:"column(partner_id);index" json:"partner_id" form:"partner_id"`
	AppId        string   `orm:"column(app_id);size(32);index" json:"app_id"`        //所属appid
	Name         string  `orm:"column(name)" json:"name" form:"name"`       // 
	Account      string  `orm:"column(account)" json:"account" form:"account"`       //
	AccountName  string  `orm:"column(account_name)" json:"account_name" form:"account_name"` //
	Network      string  `orm:"column(network)" json:"network" form:"network"`       //
	State        int     `orm:"column(state)" json:"state" form:"state"`             //
    UpdatedAt   time.Time `orm:"auto_now;column(updated_at);type(datetime)" json:"-" form:"-"` //更新时间
}

func init() {
    orm.RegisterModel(new(Account))   
}

func AddAccount(m *Account) (id int64, err error) {
	o := models.GetDefaultDB()
	id, err = o.Insert(m)
	return
}
func GetAccountById(id int64) (v *Account, err error) {
	o := models.GetDefaultDB()
	v = &Account{MemberId: id}
	if err = o.Read(v); err == nil {
		return v, nil
	}
	return nil, err
}
func GetAllAccounts(appIds []string,query map[string]string,fields []string,order_by map[string]string,offset int,limit int)([]*Account,int64,error){
	o := models.GetDefaultDB()
	qs := o.QueryTable(new(Account))
	for k, v := range query {
		k = strings.Replace(k, ".", "__", -1)
		if ok := strings.Contains(v, "|"); ok {    //in order to: in
		    valueArr := strings.Split(v, "|")
			qs = qs.Filter(k, valueArr)
		}else{
		    qs = qs.Filter(k, v)
		}	
	}
	if len(appIds) > 0 {
        qs = qs.Filter("app_id__in", appIds)
    }
	cnt, err := qs.Count()
	var sortFields []string
	for k, v := range order_by {
		orderby := ""
		if v == "desc" {
			orderby = "-" + k
		} else if v == "asc" {
			orderby = k
		} else {
			return nil, 0, errors.New("Error: Invalid order. Must be either [asc|desc]")
		}
		sortFields = append(sortFields, orderby)
	}
	qs = qs.OrderBy(sortFields...)
	var lists []*Account
	if _, err = qs.Limit(limit, offset).All(&lists, fields...); err == nil {
	   
		return lists, cnt, nil
	}
	return nil, 0, err
}
func UpdateAccountById(m *Account, param ...string) (err error) {
	o := models.GetDefaultDB()
	v := Account{MemberId: m.MemberId}
	if err = o.Read(&v); err == nil {
		if _, err = o.Update(m, param...); err == nil {
			return nil
		}
	}
	return
}
func DeleteAccount(id int64) (err error) {
	o := models.GetDefaultDB()
	v := Account{MemberId: id}
	if err = o.Read(&v); err == nil {
		if _, err = o.Delete(&v); err == nil {
			return nil
		}
	}
	return
}
